home *** CD-ROM | disk | FTP | other *** search
- /* window.c - this is where it all happens */
-
- #include <stdlib.h>
- #include "stdg.h"
- #include "bullseye.h"
-
- #define OFFSCREEN 1 /* 1=use offscreen buffers for every window */
- /* 0=draw directly to each window */
-
- short wincount = 0; /* how many windows do we have */
-
- enum Shapes { /* what shape does a window bullseye have */
- OVAL = 0,
- RECTANGLE = 1,
- TRIANGLE = 2
- };
-
- typedef struct Winfo Winfo; /* private bullseye window information */
-
- struct Winfo {
- short shape;
- short width;
- pixval fg;
- pixval bg;
-
- #if OFFSCREEN
- bitmap * b;
- short changed;
- #endif
-
- };
-
- #define winfo(w) ((Winfo *) w->data)
-
- cursor watch={
- { -9, -8},
- {0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0,
- 0x7F, 0xE0, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8,
- 0xFF, 0xF8, 0xFF, 0xF0, 0xFF, 0xF0, 0x7F, 0xE0,
- 0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0,
- },
- {0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80,
- 0x20, 0x40, 0x42, 0x20, 0x42, 0x20, 0x42, 0x30,
- 0x4E, 0x30, 0x40, 0x20, 0x40, 0x20, 0x20, 0x40,
- 0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80,
- },
- 0
- };
-
- /*
- * The next six functions are the function-call interface to
- * bullseye windows. The above data structures are private to
- * this file, and don't need to be known by anyone else.
- */
-
- void set_width(window *w, short width) /* set line width */
- {
- #if OFFSCREEN
- winfo(w)->changed = 1;
- #endif
- winfo(w)->width = width;
- fill_rect(w->b, w->b->r, WHITE);
- redraw(w);
- }
-
- void set_fore(window *w, pixval v) /* set foreground colour */
- {
- #if OFFSCREEN
- winfo(w)->changed = 1;
- #endif
- winfo(w)->fg = v;
- fill_rect(w->b, w->b->r, WHITE);
- redraw(w);
- }
-
- void set_back(window *w, pixval v) /* set background colour */
- {
- #if OFFSCREEN
- winfo(w)->changed = 1;
- #endif
- winfo(w)->bg = v;
- fill_rect(w->b, w->b->r, WHITE);
- redraw(w);
- }
-
- short get_width(window *w) /* get width of lines in window */
- {
- return winfo(w)->width;
- }
-
- pixval get_fore(window *w) /* get foreground colour */
- {
- return winfo(w)->fg;
- }
-
- pixval get_back(window *w) /* get background colour */
- {
- return winfo(w)->bg;
- }
-
- rectangle nice_rect(void) /* return a nice new rectangle for a window */
- {
- long offset;
- rectangle r = rdiag(25,45,100,100);
-
- offset = ((wincount) % 7) * 20;
-
- r = raddp(r,pt(offset,offset));
- wincount++;
-
- return r;
- }
-
- /*
- * New_bullseye creates a basic bullseye window and returns it.
- * The next three functions customise it to a given shape.
- * The function relies on the nice_rect function to provide a nice
- * location for a bullseye on screen.
- */
-
- window *new_bullseye(short shape) /* make and return a bullseye window */
- {
- window *w;
- rectangle r = nice_rect();
-
- w = new_window("Bullseye", r,
- Titlebar | Closebox | Maximize | Resize | Document);
-
- set_winfns(w, &close, &resize, &redraw);
-
- w->data = (void *) malloc(sizeof(Winfo));
- winfo(w)->shape = shape;
- winfo(w)->width = 5;
- winfo(w)->fg = BLACK;
- winfo(w)->bg = WHITE;
-
- #if OFFSCREEN
- winfo(w)->b = new_bitmap(r, 0); /* bitmap size & depth of window */
- winfo(w)->changed = 1; /* remember that this window needs redrawing */
- #endif
-
- return w;
- }
-
-
- void new_oval(void) /* create new oval shape and show it */
- {
- window *w = new_bullseye(OVAL);
-
- set_winname(w, "Oval");
- show_window(w);
- }
-
- void new_rectangle(void) /* create new rectangular shape and show it */
- {
- window *w = new_bullseye(RECTANGLE);
-
- set_winname(w, "Rectangle");
- show_window(w);
- }
-
- void new_triangle(void) /* create new triangular shape and show it */
- {
- window *w = new_bullseye(TRIANGLE);
-
- set_winname(w, "Triangle");
- show_window(w);
- }
-
- /*
- * This function is called from main when someone does a mouse click
- * in a bullseye window.
- */
-
- void hit_window(window *w) /* handle mouse down in the window */
- {
- fill_rect(w->b, w->b->r, WHITE);
- redraw(w);
- }
-
- /*
- * Close happens whenever a bullseye window is closed.
- */
-
- void close(window *w) /* close a window */
- {
- #if OFFSCREEN
- del_bitmap(winfo(w)->b);
- #endif
- free(w->data);
- del_window(w);
- }
-
- /*
- * Paint_oval is the expert that knows how to paint a single oval
- * of a given thickness, colour and size to a bitmap.
- */
-
- void paint_oval(bitmap *b, rectangle r, short width, pixval v)
- {
- point p0;
- long r1, r2;
- short w;
-
- p0 = divp(addp(r.min,r.max),2);
- r1 = dx(r)/2;
- r2 = dy(r)/2;
- w = width;
-
- while(w > 0) {
- draw_ellipse(b, p0, r1, r2, v);
- r1--;
- r2--;
- w--;
- }
- }
-
- /*
- * Paint_rectangle uses draw_rect, which uses fill_rect. This makes
- * it faster than the other drawing operations.
- */
-
- void paint_rectangle(bitmap *b, rectangle r, short width, pixval v)
- {
- short w;
-
- w = width;
-
- if (w > dx(r))
- w = dx(r);
- if (w > dy(r))
- w = dy(r);
-
- draw_rect(b, r, w, v);
- }
-
- /*
- * Paint_triangle is similar to the THINK C Bullseye triangle shape.
- * It doesn't draw properly inset triangles due to the way the
- * target rectangle is stepped inwards.
- */
-
- void paint_triangle(bitmap *b, rectangle r, short width, pixval v)
- {
- point p1, p2, p3;
- short w;
-
- p1 = r.min;
- p2 = pt(r.min.x, r.max.y);
- p3 = r.max;
- w = width;
-
- while(w > 0) {
- draw_line(b, p1, p2, v);
- draw_line(b, p2, p3, v);
- draw_line(b, p3, p1, v);
- p1 = addp(p1,pt(1,2));
- p2 = addp(p2,pt(1,-1));
- p3 = addp(p3,pt(-2,-1));
- w--;
- }
- }
-
- /*
- * Resize is called when a window is resized. Redraw is called afterwards.
- * Here we change the size of the window's offscreen buffer.
- */
- void resize(window *w)
- {
- #if OFFSCREEN
- winfo(w)->changed = 1;
- del_bitmap(winfo(w)->b);
- winfo(w)->b = new_bitmap(w->r, 0);
- #endif
- }
-
- /*
- * Draw does the drawing to a bitmap (could be the window bitmap).
- * It is given some bullseye info and calls the appropriate
- * paint_shape function repeatedly with inward stepping rectangles.
- */
-
- void draw(bitmap *b, short width, short shape, pixval fg, pixval bg)
- {
- rectangle r = b->r;
-
- set_cursor(&watch);
-
- fill_rect(b, r, bg); /* draw background colour */
-
- while(dx(r) > 0 && dy(r) > 0) { /* step rectangle inwards */
- switch (shape) {
- case OVAL: paint_oval(b, r, width, fg); break;
- case RECTANGLE: paint_rectangle(b, r, width, fg); break;
- case TRIANGLE: paint_triangle(b, r, width, fg); break;
- }
- r = insetr(r, width*2);
- }
-
- set_cursor(NULL);
- }
-
- /*
- * Redraw is called whenever a window needs redrawing.
- * It calls draw if drawing directly to the window, or if the offscreen
- * bitmap needs redrawing.
- * It calls bit_copy to refresh the window from the offscreen bitmap,
- * if an offscreen bitmap exists.
- */
-
- void redraw(window *w)
- {
- #if OFFSCREEN
- if (winfo(w)->changed) {
- draw(winfo(w)->b, winfo(w)->width, winfo(w)->shape,
- winfo(w)->fg, winfo(w)->bg);
- winfo(w)->changed = 0;
- }
- bit_copy(w->b, pt(0,0), winfo(w)->b, winfo(w)->b->r, S);
- #else
- draw(w->b, winfo(w)->width, winfo(w)->shape,
- winfo(w)->fg, winfo(w)->bg);
- #endif
- }
-